package protocol

import (
	"strconv"
)

const CRLF = "\r\n"

type StatusReply struct {
	Status string
}

func (s *StatusReply) ToBytes() []byte {
	return []byte("+" + s.Status + CRLF)
}

func MakeStatusReply(content string) *StatusReply {
	return &StatusReply{
		Status: content,
	}
}

type ErrorReply struct {
	Msg string
}

func MakeErrorReply(msg string) *ErrorReply {
	return &ErrorReply{
		Msg: msg,
	}
}

func (r *ErrorReply) ToBytes() []byte {
	return []byte("-" + r.Msg + CRLF)
}

type MultiBulkReply struct {
	Args [][]byte
}

func (r *MultiBulkReply) ToBytes() []byte {
	var buf []byte
	buf = append(buf, '*')
	buf = strconv.AppendInt(buf, int64(len(r.Args)), 10)
	buf = append(buf, CRLF...)
	for _, arg := range r.Args {
		buf = append(buf, '$')
		buf = strconv.AppendInt(buf, int64(len(arg)), 10)
		buf = append(buf, CRLF...)
		buf = append(buf, arg...)
		buf = append(buf, CRLF...)
	}
	return buf
}

type IntReply struct {
	Value int64
}

func MakeIntReply(value int64) *IntReply {
	return &IntReply{
		Value: value,
	}
}

func (r *IntReply) ToBytes() []byte {
	return []byte(":" + strconv.FormatInt(r.Value, 10) + CRLF)
}

type BulkReply struct {
	Value []byte
}

func MakeBulkReply(value []byte) *BulkReply {
	return &BulkReply{
		Value: value,
	}
}

func (r *BulkReply) ToBytes() []byte {
	return []byte("$" + strconv.Itoa(len(r.Value)) + CRLF + string(r.Value) + CRLF)
}

func MakeNullBulkReply() *BulkReply {
	return &BulkReply{
		Value: nil,
	}
}

func MakeMultiBulkReply(args [][]byte) *MultiBulkReply {
	return &MultiBulkReply{
		Args: args,
	}
}

type PongReply struct {
}

var pongBytes = []byte("+PONG\r\n")

func (r *PongReply) ToBytes() []byte {
	return pongBytes
}
